//1.不可变数据 immer原理 produce
const Internal=Symbol('internal')
function produce(targetState,producer){
   const proxyState=toProxy(targetState)
    producer(proxyState)
    return proxyState[Internal].change?proxyState[Internal].copyState:proxyState[Internal].targetState
}
function toProxy(targetState,callBack=()=>{}){
  const internal={
    targetState,
    keyToProxy:{},
    change:false,
    copyState:createCopy(targetState)
  }
  return new Proxy(targetState,{
     get(_,key){
         if(key===Internal){
            return internal
         }
         if(key in internal.keyToProxy){
            return internal.keyToProxy[key]
         }else{
           const value= targetState[key]
            if(typeof value==='object'){
                 internal.keyToProxy[key]=toProxy(value,()=>{
                  internal.change=true
                  const proxyChild = internal.keyToProxy[key];
                  internal.copyState[key]=proxyChild[Internal].copyState
                  callBack()
                 })
            }
         }
         return  internal.keyToProxy[key]
     },
     set(_,key,value){
        internal.change=true
        internal.copyState[key]=value
        callBack()
        return true
     }
  })
}
function createCopy(targetState){
  if(Array.isArray(targetState)){
   return [...targetState]
  }else{
   return {...targetState}
  }
}

let obj={
   obj1:{
       obj2:{
           obj3:{
               name:'obj3'
           }
       }
   },
   name:'name',
   obj4:{
       name:'obj4'
   }
}
let newObj1=produce(obj,(pObj)=>{
   pObj.obj4.name='obj4xxx'
})
console.log(newObj1.obj1===obj.obj1)
console.log(newObj1.obj4===obj.obj4)
console.log(newObj1,obj)